<template>
  <div
    class="el-cascader el-cascader--medium"
    @click.stop="() => toggleDropDownVisible(undefined)"
    v-clickoutside="() => toggleDropDownVisible(false)"
  >
    <el-input
      ref="reference"
      v-model="selectedLabel"
      type="text"
      :placeholder="placeholder"
      :name="name"
      :id="id"
      :size="size"
      :autocomplete="autocomplete"
      :disabled="disabled"
      :readonly="true"
      :validate-event="false"
      :class="{ 'is-focus': visible }"
      @keydown.native.esc.stop.prevent="visible = false"
      @keydown.native.tab="visible = false"
      @mouseenter.native="inputHovering = true"
      @mouseleave.native="inputHovering = false"
      @click.native.stop="toggerVisible"
    >
      <template slot="prefix" v-if="$slots.prefix">
        <slot name="prefix"></slot>
      </template>
      <template slot="suffix">
        <i
          v-show="!showClose"
          :class="['el-icon-arrow-down', 'el-input__icon', visible && 'is-reverse']"
        ></i>
        <i
          v-if="showClose"
          class="el-input__icon el-icon-circle-close"
          @click="handleClearClick"
        ></i>
      </template>
    </el-input>

    <div class="el-cascader__tags">
      <el-tag
        v-for="tag in presentTags"
        :key="tag.id"
        type="info"
        disable-transitions
        :closable="false"
        @close="deleteTag(tag)"
      >
        <span>{{ tag.geo_name }}</span>
      </el-tag>
    </div>

    <transition name="el-zoom-in-top">
      <div class="el-select-dropdown el-popper" x-placement="bottom-start" v-show="visible">
        <select-area-panel
          :no-data-text="noDataText"
          ref="panel"
          v-model="innerValue"
          @change="handleChange"
          @init="handleInit"
        ></select-area-panel>
        <div x-arrow class="popper__arrow" style="left: 35px"></div>
      </div>
    </transition>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import Clickoutside from 'element-ui/src/utils/clickoutside'
import SelectAreaPanel from '@/credit/components/select/SelectAreaPanel'

const isEqual = (arr1, arr2) => {
  if (arr1.length !== arr2.length) return false
  for (const val of arr1) {
    if (!arr2.includes(val)) {
      return false
    }
  }
  return true
}

export default {
  components: {
    SelectAreaPanel,
  },
  directives: { Clickoutside },
  props: {
    name: String,
    id: String,
    value: {
      type: String,
      required: true,
    },
    autocomplete: {
      type: String,
      default: 'off',
    },
    size: String,
    disabled: Boolean,
    placeholder: {
      type: String,
      default() {
        return '请选择'
      },
    },
    multiple: {
      type: Boolean,
      default: true,
    },
    clearable: Boolean,
    loading: Boolean,
    noDataText: {
      type: String,
      default: '暂无数据',
    },
  },
  model: {
    prop: 'value',
    event: 'change',
  },
  data() {
    return {
      visible: false,
      selectedLabel: null,
      inputHovering: false,
      innerValue: [],
      presentTags: [],
      inputInitialHeight: 0,
    }
  },
  computed: {
    ...mapGetters(['user']),
    showClose() {
      let hasValue = this.multiple
        ? Array.isArray(this.value) && this.value.length > 0
        : this.value !== undefined && this.value !== null && this.value !== ''
      return this.clearable && !this.disabled && this.inputHovering && hasValue
    },
  },
  watch: {
    value: {
      handler: function (val) {
        const arr = val ? val.split(',') : []
        if (!isEqual(arr, this.innerValue)) {
          this.innerValue = arr
        }
      },
      immediate: true,
      deep: true,
    },
    presentTags(val, oldVal) {
      this.selectedLabel = val && val.length ? ' ' : ''
      if (val.length || oldVal.length) {
        this.$nextTick(this.updateStyle)
      }
    },
  },
  created() {},
  mounted() {
    const { reference } = this.$refs
    if (reference && reference.$el) {
      this.inputInitialHeight = reference.$el.offsetHeight || 40
    }
  },
  methods: {
    handleChange(row) {
      this.presentTags = row
      this.$emit('change', row.map(item => item.id).join(','), row)
    },
    handleInit(row) {
      this.presentTags = row
    },
    toggleDropDownVisible(visible) {
      if (this.disabled) return

      visible = visible !== void 0 ? visible : !this.visible
      if (visible !== this.visible) {
        this.visible = visible
      }
    },
    toggerVisible() {
      this.visible = !this.visible
    },
    handleClose() {
      this.visible = false
    },
    deleteTag(tag) {
      const { panel } = this.$refs
      if (!panel) return
      panel.removeNode(tag)
    },
    updateStyle() {
      const { $el, inputInitialHeight } = this
      if (!this.$el) return

      const inputInner = $el.querySelector('.el-input__inner')
      if (!inputInner) return

      const tags = $el.querySelector('.el-cascader__tags')
      if (tags) {
        const { offsetHeight } = tags
        inputInner.style.height = Math.max(offsetHeight + 6, inputInitialHeight) + 'px'
      }
    },
  },
}
</script>
<style lang="scss" scoped></style>
